/**
 *
 */
package kevin.study.zephyr.domain.model.view;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import kevin.study.zephyr.domain.model.Document;
import kevin.study.zephyr.domain.model.Field;
import kevin.study.zephyr.domain.model.base.Base;
import kevin.study.zephyr.domain.model.view.soda.VQuery;
import kevin.study.zephyr.platform.Platform;
import kevin.study.zephyr.util.StringUtils;

/**
 * View
 *
 * @author Kevin.Huang
 * @createtime 2007-9-20
 */
public class View extends Base {

	/**
	 *
	 */
	private static final long serialVersionUID = 7993573246316193851L;

	private String condition;

	private List<ViewColumn> columns;


	private VQuery convertQuery() {
		VQuery vq = new VQuery();
		Binding binding = new Binding();
		binding.setVariable("_query", vq);
		GroovyShell gs = new GroovyShell(binding);
		String script = "";
		for (String cond : perpareCondition()) {
			script = script + "_query." + cond + ";\n";
		}
		gs.evaluate(script);
		return vq;
	}

	private List<String> perpareCondition() {
		if (condition == null) {
			return new ArrayList<String>();
		}
		String[] draft = condition.split(";");
		List<String> result = new ArrayList<String>();
		for (String r : draft) {
			if (StringUtils.hasLength(r.replaceAll("\n", "").replaceAll("\r", "").trim())) {
				result.add(r.replaceAll("\n", "").replaceAll("\r", "").trim());
			}
		}
		return result;
	}

	/**
	 * 根据输入条件取得Document
	 *
	 * @return
	 */
	public Collection<Document> getResultDocument() {
		return Platform.getDocumentManager().getDocumentDAO().findByQuery(this.convertQuery().getZQuery());
	}

	/**
	 * 根据输入条件取得Document总数
	 *
	 * @return
	 */
	public Integer getResultDocumentCount() {
		return Platform.getDocumentManager().getDocumentDAO().findCountByQuery(
				this.convertQuery().getZQuery());
	}

	/**
	 * 根据输入条件取得Document
	 *
	 * @return
	 */
	public Collection<Document> getResultDocumentByPage(int index, int count) {
		return Platform.getDocumentManager().getDocumentDAO().findByQuery(this.convertQuery().getZQuery(),
				index, count);
	}

	/**
	 * 获取RowEntity
	 *
	 * @return
	 */
	public Collection<RowEntity> getRowCollection() {
		Collection<Document> docs = getResultDocument();
        return createRowEntity(docs);
	}

	/**
	 * 获取RowEntity(分页)
	 *
	 * @return
	 */
	public Collection<RowEntity> getRowCollectionByPage(int index, int count) {
		Collection<Document> docs = getResultDocumentByPage(index, count);
        return createRowEntity(docs);
	}

    private Collection<RowEntity> createRowEntity(Collection<Document> docs) {
        Collection<RowEntity> rows = new ArrayList<RowEntity>();
        Collection<Field> columnFields = getColumnFields();
        for (Document doc : docs) {
            rows.add(new RowEntity(doc, columnFields));
        }
        return rows;
    }

    /**
	 * 获取ColumnEntity
	 *
	 * @return
	 */
	public ColumnEntity getColumnCollectionByField(Field field) {
		Collection<Document> docs = getResultDocument();
        return createColumnEntity(field, docs);
	}

    private ColumnEntity createColumnEntity(Field field, Collection<Document> docs) {
        Collection<Field> columnFields = getColumnFields();
        if (!columnFields.contains(field)) {
            throw new RuntimeException(field.getName() + " is a invaild field!");
        }
        return new ColumnEntity(docs, field);
    }

    /**
	 * 获取ColumnEntity(分页)
	 *
	 * @return
	 */
	public ColumnEntity getColumnCollectionByFieldAndPage(Field field, int index, int count) {
		Collection<Document> docs = getResultDocumentByPage(index, count);
        return createColumnEntity(field, docs);
	}

	private Collection<Field> getColumnFields() {
		Collection<Field> fields = new ArrayList<Field>();
		if (this.columns != null && !this.columns.isEmpty()) {

			for (ViewColumn vc : this.columns) {
				fields.add(vc.getField());
			}
		}
		return fields;
	}

	/**
	 * 保存视图
     * @return The Saved View
	 */
	public View save() {
		return Platform.getViewManager().getViewDAO().saveAndUpdate(this);
	}

	/**
	 * @return the columns
	 */
	public List<ViewColumn> getColumns() {
		return columns;
	}

	/**
	 * @param columns
	 *            the columns to set
	 */
	public void setColumns(List<ViewColumn> columns) {
		this.columns = columns;
		Collections.sort(this.columns);
	}

	/**
	 * @return the condition
	 */
	public String getQuery() {
		return condition;
	}

	/**
	 * @param condition
	 *            the condition to set
	 */
	public void setQuery(String condition) {
		this.condition = condition;
	}

}
